package com.ftw.commons.widgets


import android.app.Activity
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.graphics.PixelFormat
import android.graphics.Rect
import android.os.IBinder
import android.util.DisplayMetrics
import android.view.Gravity
import android.view.KeyEvent
import android.view.View
import android.view.WindowManager
import android.widget.PopupWindow
import com.trello.rxlifecycle3.components.support.RxAppCompatActivity
import com.ftw.commons.utils.OsUtils
import com.ftw.commons.utils.ZPopupWindowUtil


/**
 * @Description:
 * @Author: fangtianwen
 * @Date: 2020/1/9 15:17
 */
abstract class ZPopupWindow// 注册相应广播
    (context: RxAppCompatActivity) : PopupWindow(context) {

    private var wm: WindowManager? = null
    private var maskView: View? = null
    private var maskHeight = 0
    private var maskGravity: Int = Gravity.CENTER
    var mContext: RxAppCompatActivity = context


    // 获取自定义View
    abstract fun getView(context: Context?): View?

    //定义动画效果
    abstract fun getAnimationStyles(): Int

    //获取popwindowd高度
    abstract fun getPopWindwindHeight(): Int

    abstract fun getPopWindwindWidth(): Int


    /**
     * 设定处理距离
     */
    abstract fun isVerticalMargin(): Boolean

    override fun showAtLocation(anchor: View, gravity: Int, x: Int, y: Int) {
        addMaskView(anchor.windowToken, maskHeight, maskGravity)
        super.showAtLocation(anchor, gravity, 0, 0)
    }

    override fun showAsDropDown(anchor: View, xoff: Int, yoff: Int) {
        addMaskView(anchor.windowToken, maskHeight, maskGravity)
        super.showAsDropDown(anchor, xoff, yoff)
    }

    override fun dismiss() {
        // 刷新界面
        removeMaskView()
        super.dismiss()
    }

    /**
     * 显示在界面的底部
     */
    open fun showBottom() {
        regReceiver()
        showAtLocation(
            (mContext).window.decorView,
            Gravity.BOTTOM or Gravity.CENTER_HORIZONTAL,
            0,
            0
        )
    }

    /**
     * 显示在界面的顶部
     */
    open fun showTop() {
        regReceiver()
        showAtLocation(
            (mContext).window.decorView,
            Gravity.TOP or Gravity.CENTER_HORIZONTAL,
            0,
            0
        )
    }

    /**
     * 显示在界面的顶部
     */
    open fun showLeft() {
        regReceiver()
        val frame = Rect()
        mContext.window.decorView.getWindowVisibleDisplayFrame(frame)
        maskHeight = frame.height()
        showAtLocation(
            (mContext).window.decorView,
            Gravity.TOP or Gravity.START,
            0,
            0
        )
    }


    /**
     * 显示在指定View的正上方
     *
     * @param view    指定的View
     * @param yOffset Y轴偏移量
     */
    open fun showViewTop(view: View, yOffset: Int) {
        regReceiver()
//        maskHeight = getScreenH(mContext) - view.height - yOffset
        // 获取需要在其上方显示的控件的位置信息
        val location = IntArray(2)
        view.getLocationOnScreen(location)
        // 获取自身的长宽高
        this.contentView.measure(
            View.MeasureSpec.UNSPECIFIED,
            View.MeasureSpec.UNSPECIFIED
        )
        val popupHeight = this.contentView.measuredHeight
        val popupWidth = this.contentView.measuredWidth
        //在控件上方显示
        maskGravity = Gravity.TOP or Gravity.CENTER_HORIZONTAL
        showAtLocation(
            view,
            Gravity.NO_GRAVITY,
            location[0] + popupWidth / 2,
            location[1] - popupHeight - yOffset
        )
    }

    /**
     * 显示在指定View的正下方
     *
     * @param view    指定的View
     * @param yOffset Y轴偏移量
     */
    open fun showViewBottom(view: View, yOffset: Int) {
        maskHeight =
            getScreenH(mContext) - getStatusHeight(mContext) - view.height - yOffset
        maskGravity = Gravity.BOTTOM or Gravity.CENTER_HORIZONTAL
        showAsDropDown(view, 0, yOffset)
    }

    // 注册广播接收器，接收暗屏广播，锁屏广播
    private fun regReceiver() {
        val filter = IntentFilter()
        filter.addAction(Intent.ACTION_SCREEN_OFF)
        filter.addAction(Intent.ACTION_USER_PRESENT)
        // 广播开启的同时，添加到管理类
        ZPopupWindowUtil.clearZPopupWindows()
        ZPopupWindowUtil.addZPopupWindow(this)
    }

    // 添加遮罩层
    private fun addMaskView(token: IBinder, maskHeight: Int, gravity: Int) {
        val params =
            WindowManager.LayoutParams()
        params.width = WindowManager.LayoutParams.MATCH_PARENT
        params.height = maskHeight
        if (isVerticalMargin()) {
            params.verticalMargin = OsUtils.getCurrentNavigationBarHeight(mContext).toFloat()
        }
        params.format = PixelFormat.TRANSLUCENT
        params.type = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL
        params.token = token
        params.gravity = gravity
        maskView = View(mContext)
        maskView!!.setBackgroundColor(-0x61000000)
        maskView!!.fitsSystemWindows = false
        maskView!!.setOnKeyListener(object : View.OnKeyListener {
            override fun onKey(v: View?, keyCode: Int, event: KeyEvent?): Boolean {
                if (keyCode == KeyEvent.KEYCODE_BACK) {
                    removeMaskView()
                    return true
                }
                return false
            }
        })
        wm!!.addView(maskView, params)
    }

    // 移除遮罩层
    private fun removeMaskView() {
        if (maskView != null) {
            wm!!.removeViewImmediate(maskView)
            maskView = null
        }
    }

    /**
     * 获取屏幕高度（包括状态栏的高度） - px
     */
    private fun getScreenH(aty: Activity): Int {
        val wm =
            aty.getSystemService(Context.WINDOW_SERVICE) as WindowManager
        val outMetrics = DisplayMetrics()
        wm.defaultDisplay?.getMetrics(outMetrics)
        return outMetrics.heightPixels
    }

    /**
     * 获取状态栏高度
     */
    private fun getStatusHeight(activity: Activity): Int {
        val frame = Rect()
        activity.window.decorView.getWindowVisibleDisplayFrame(frame)
        return frame.top
    }

    init {
        maskHeight = getScreenH(mContext)
        wm = mContext.getSystemService(Context.WINDOW_SERVICE) as WindowManager
        contentView = getView(mContext)
        width = getPopWindwindWidth()
        height = getPopWindwindHeight()
        isOutsideTouchable = true
        isFocusable = true
        setBackgroundDrawable(mContext.resources.getDrawable(android.R.color.transparent))
        val animationStyles = getAnimationStyles()
        if (animationStyles > -1) {
            animationStyle = getAnimationStyles()
        }
    }


}